package com.incross.dawin.views;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpResponse;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;

import com.incross.dawin.DawinConfig;
import com.incross.dawin.http.BKConnectionManager;
import com.incross.dawin.http.parser.AdditionalInfoParser.SnsShare;
import com.incross.dawin.http.parser.AdditionalInfoParser.TickerAd;
import com.incross.dawin.http.parser.BKAdInfoParser;
import com.incross.dawin.http.parser.IconInfoParser;
import com.incross.dawin.objects.AdInfos;
import com.incross.dawin.util.BKErrorHandler;
import com.incross.dawin.util.BKImageDownloader;
import com.incross.dawin.util.BKImageDownloader.OnBitmapDownloadFinishListener;
import com.incross.dawin.util.BKLog;
import com.incross.dawin.util.CommonUtils;
import com.incross.dawin.util.CommonUtils.ScreenSize;
import com.incross.dawin.util.TickerAdBuilder;
import com.incross.dawin.util.TickerAdBuilder.Ticker;
import com.incross.dawin.util.TickerAdBuilder.TickerInfo;
import com.incross.dawin.views.BKDialog.OnDialogStateListener;
import com.incross.dawin.views.BKVideoPlayer.OnSizeAdjustListener;
import com.incross.dawin.views.BKVideoPlayer.OnVideoErrorListener;

public class DawinAdPlayer extends LinearLayout implements BKConnectionManager.RequestStateListener, BKDialog.OnDialogStateListener {
	private static final int REQUEST_START = 1000;
	private static final int REQUEST_QUARTER = 1100;
	private static final int REQUEST_QUEARTER2 = 1200;
	private static final int REQUEST_QUEARTER3 = 1300;
	private static final int REQUEST_FINISHED = 1400;
	private static final int REQUEST_SKIP = 1500;
	private static final int REQUEST_ERROR = 1600;
	private static final int REQUEST_AD_INFOS = 1700;
	private static final int REQUEST_CHARGE = 1900;
	private static final int REQUEST_PHONE_CLICK = 2000;
	private static final int REQUEST_SEND_TAG = 2100;
	
	public static final int ICON_CLICK_STOP = 123;
	public static final int ICON_CLICK_PAUSE = 456;
	
	public static final int BROWSER_MODE_INTERNEL = 10000;
	public static final int BROWSER_MODE_WEBVIEW = 20000;
	public static final int WEBVIEW_FULL = 21000;
	public static final int WEBVIEW_DIALOG = 22000;
	
	public static final int AD_FINISH_ACTION_COMPLETE = 30000;
	public static final int AD_FINISH_ACTION_SKIP = 31000;
	public static final int AD_FINISH_SCREEN_CLICK = 32000;
	public static final int AD_FINISH_ACTION_BUTTON_CLICK = 33000;
	public static final int AD_FINISH_CALL_ACTION = 34000;
	public static final int AD_FINISH_NO_APPLICABLE_AD = 35000;
	public static final int AD_FINISH_BACK_KEY_PRESSED = 35100;
	public static final int AD_FINISH_AFTER_ACTION = 35200;
	public static final int AD_FINISH_BY_SNS_SHARE = 35250;
	public static final int AD_FINISH_AFTER_SNS_SHARE = 35310;
	public static final int AD_FINISH_BY_TICKER = 35400;
	public static final int AD_FINISH_AFTER_TICKER = 35450;
	public static final int AD_FINISH_OTHER_REASON = 35300;
	
	public static final int AD_FINISH_NETWORK_DISCONNECTED = 36000;
	public static final int AD_FINISH_AD_INFO_RECEIVE_FAIL = 36100;
	public static final int AD_FINISH_OTHER_ERROR = 36200;
	
	private static final int QUARTER_CHECK_TIMER = 10;
	private static final int CHARGE_TIMER = 11;
	private static final int SKIP_TIMER = 12;
	private static final int COMBINED_TIMER = 13;
	
	private static final int MESSAGE_SHOW_SKIP = 100;
	private static final int MESSAGE_HANDLE_TICKER = 101;
	private static final int MESSAGE_REMOVE_TICKER = 102;
	private static final int MESSAGE_RESET_VIEW = 103;
	
	private static final int CALL_STATE_IDLE = 40000;
	private static final int CALL_STATE_INCOMING = 41000;
	private static final int CALL_STATE_OUTGOING = 42000;
	
	// 송출기 응답없을시 로그 수집 url
	private static final String ADINFO_ERROR_LOG_REL = "http://adm.dawin.tv/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	private static final String ADINFO_ERROR_LOG_DEV = "http://112.169.59.42:9090/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	
	private int mCurrentOrientation;
	
	private int mDawinServerType = DawinConfig.DAWIN_SERVER_TEST;
	
	private final int MAX_RETRY_COUNT = 2;
	private final String AD_INFO_URL = "http://ads.dawin.tv/imp";//"http://112.169.59.43/imp";
	private final String AD_INFO_TEST_URL = "http://112.169.59.43/imp";
	
	private JSONObject mAdInfoParameter;
	
	private Context mContext;
	private AttributeSet mAttributeSet;
	private int mDefStyle;
	
	private int mAdDuration;
	
	private int mDialogMarginRate = 5;
	
	private RelativeLayout mVideoLayout, mTopLayout, mBottomLayout, mLeftLayout, mRightLayout;
	private BKVideoPlayer mVideoPlayer;
	
	private ImageButton mFacebookButton, mTwitterButton, mSkipButton, mSkipDescriptionButton;
	private ImageButton mCallButton, mMapButton, mEventButton, mDownloadButton;
	
	private LinearLayout mSnsLayout, mEventLayout, mCallLayout, mDownloadLayout, mMapLayout, mSkipLayout, mShareLayout, mVideoBottomLayout;
	
	// Add views for snsShare
	private LinearLayout mSnsShareContentLayout;
	private RelativeLayout mSnsBottomLayout;
	private ImageButton mSnsShareButton;
	private boolean mIsSnsEtcButtonClicked = false;
	
	private OnPlayFinishListener mPlayFinishListener;
	private OnErrorListener mErrorListener;
	private OnPreparedListener mPreparedListener;
	private OnTimeListener mTimeListener;
	
	private BKConnectionManager mConnectionManager;
	
	private ProgressBar mProgress;
	
	private AdInfos mAdInfos;
	private BKImageDownloader mImageDownloader;
	private int mQuarter, mQuarter2, mQuarter3;
	private int mCurrentQuarter = 1;
	private int mLastSendedTag = 0;
	private MediaController mMediaController;
	private boolean mIsStartTagSended = false;
	
	private boolean mIsVideoClickProcessing = false;
	
	private boolean mIsDawinPlaying = false;
	
	// flags for call(incoming outgoing)
	private int mCurrentCallState = CALL_STATE_IDLE;
	
	
	private int mButtonSize = 60;
	private int mSkipButtonWidth = 150;
	private int mSkipDescWidth = 468;
	private int mSkipButtonHeight = 156;
	
	// 20140922 Action button size changed. xhdpi 기준 사이즈
	private int mActionButtonWidth = 80;
	private int mActionButtonHeight = 80;
	
	private boolean mIsClickviewerShown = false;
	private boolean mIsOnPauseCalled = false;
	private boolean mIsSnsShareClicked = false;
	private boolean mIsTickerClicked = false;
	
	private int mAdInfoRetryCount = 0;
	private int mChargeTagRetryCount = 0;
	
	private boolean mIsChargeTagSendSucceed = false;
	
	private int mDeviceDensity;
	
	private BKErrorHandler mErrorHandler;
	
	private int mChargeTime = 0;
	
	private String xmlString;
	
	private int mPortParentWidth = -1;
	private int mPortParentHeight = -1;
	
	private int mLandParentWidth = -1;
	private int mLandParentHeight = -1;
	
	// 광고 요청 url 저장 : 광고정보 수신 실패시 서버에 보내는 용도.
	private String mAdinfoRequestUrl = "";
	
	// skip timer.
	private Timer mSkipTimer;
	private TimerTask mSkipTimerTask;
	private boolean mIsSkipTimerRunning = false;
	
	// charge timer
	private Timer mChargeTimer;
	private TimerTask mChargeTimerTask;
	private boolean mIsChargeTimerRunning = false;
	
	// quarter check timer
	private Timer mQuarterTimer;
	private TimerTask mQuarterTimerTask;
	private boolean mIsQuarterTimerRunning = false;
	
	private int mTimerPeriod = 100;
	private int mTimerDelay = 0;
	
	// 통합 timer
	private Timer mTimer;
	private TimerTask mTimerTask;
	private boolean mIsTimerRunning = false;
	
	
	// 15초 광고인 경우 과금태그를 광고가 끝나는 시점에 호출하기 위해 체크
	private boolean mIsQuarterMinAd = false;
	
	// T store 설치여부 저장하는 flag
	private boolean mIsTstoreInstalled = false;
	
	// kakao talk, kakao story 설치여부 저장하는 flag
	private boolean mIsKakaoTalkInstalled = false;
	private boolean mIsKakaoStoryInstalled = false;
	
	// 20141216 sns Share처럼 버튼을 무더기로 넣는 경우 참고 변수
	private boolean mIsButtonClickable = false;
	
	// ticker 관련 변수
	private Ticker mTicker = null;
	private boolean mIsTickerShowing = false;
	private int mCurrentTickerNum = 0;
	private int mCurrentShowingTickerOrientation = -1;
	
	private ImageButton mPortTickerButton, mLandTickerButton;
	
	private boolean mIsVideoLayoutHeightAdjusted = false;
	
	// 20141223 전화가능여부 판단을 위해 현재 ServiceState 값 저장할 변수 추가.
	private int mCurrentPhoneState = ServiceState.STATE_OUT_OF_SERVICE;
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
				case MESSAGE_SHOW_SKIP:
					if(mSkipButton != null) {
						mSkipDescriptionButton.setVisibility(View.GONE);
						mSkipButton.setVisibility(View.VISIBLE);
					}
					break;
					
				case MESSAGE_HANDLE_TICKER:
					if(mIsDawinPlaying) {
						handleTickerView();
					}
					
					break;
					
				case MESSAGE_REMOVE_TICKER:
					removeTickerView();
					break;
					
				case MESSAGE_RESET_VIEW:
					resetViewStates();
					break;
			}
		}
	};
	
	public interface OnTimeListener {
		public abstract void OnTime(int currMsec);
	}
	
	private void registPhoneStateListener() {
		TelephonyManager tManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 
		tManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		tManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
	}
	
	private PhoneStateListener serviceStateListener = new PhoneStateListener() {
		@Override
	    public void onServiceStateChanged (ServiceState serviceState) { // 20141223 ServiceState change 추가
	        super.onServiceStateChanged(serviceState);

	        switch(serviceState.getState()) {
	            case ServiceState.STATE_EMERGENCY_ONLY: 
	            	mCurrentPhoneState = ServiceState.STATE_EMERGENCY_ONLY;
	                BKLog.i("--- STATE_EMERGENCY_ONLY ---");
	                break;
	            case ServiceState.STATE_IN_SERVICE:
	            	mCurrentPhoneState = ServiceState.STATE_IN_SERVICE;
	            	BKLog.e("--- STATE_IN_SERVICE ---");
	                break;
	            case ServiceState.STATE_OUT_OF_SERVICE:
	            	mCurrentPhoneState = ServiceState.STATE_OUT_OF_SERVICE;
	            	BKLog.e("--- STATE_OUT_OF_SERVICE ---");
	                break;
	            case ServiceState.STATE_POWER_OFF:
	            	mCurrentPhoneState = ServiceState.STATE_POWER_OFF;
	            	BKLog.e("--- STATE_POWER_OFF ---");
	                break;
	            default:
	            	mCurrentPhoneState = ServiceState.STATE_OUT_OF_SERVICE;
	            	BKLog.e("--- Unknown ---");
	                break;
	        }   
	    }
	};
	
	private PhoneStateListener phoneStateListener = new PhoneStateListener() {
		public void onCallStateChanged(int state, String incomingNumber) {// 전화 수신 반응.
			 // 착신 전화 번호를 받는다.
			 switch (state) {
				 case TelephonyManager.CALL_STATE_IDLE :  
					 break; // 폰이 울리거나 통화중이 아님.o
				 case TelephonyManager.CALL_STATE_RINGING :
					 mCurrentCallState = CALL_STATE_INCOMING;
					 
					 if(mVideoPlayer != null && mVideoPlayer.isPlaying()) {
						 mVideoPlayer.pause();
					 }
//					 if(mPlayFinishListener != null) {
//						 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
//						 mIsClickviewerShown = true;
//					 }
					 reset();
					 
					 break; // 폰이 울린다.
				 case TelephonyManager.CALL_STATE_OFFHOOK :
					 break; // 폰이 현재 통화 중.
				 default:      
					 break;
			 }
		 }
	};
	
	public interface OnAdViewStateListener {
		public abstract void onPrepared(MediaPlayer mp);
		public abstract void onHttpRequestError();
	}
	
	
	public interface OnPlayFinishListener {
		public abstract void onPlayFinished(DawinAdPlayer dawinPlayer, int finishedBy);
	}
	
	public interface OnPreparedListener {
		public abstract void onPrepared();
	}
	
	/**
	 * same as MediaPlayer.OnErrorListener
	 */
	public interface OnErrorListener {
		public abstract void onError(MediaPlayer mp, int what, int extra);
	}
	
	public DawinAdPlayer(Context context) {
		super(context);
		mContext = context;
		init();
		setViews();
	}
	
	public DawinAdPlayer(Context context, AttributeSet attrs) {
		super(context, attrs);
		mAttributeSet = attrs;
		mContext = context;
		init();
		setViews();
	}
	
	public DawinAdPlayer(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs);
		mAttributeSet = attrs;
		mDefStyle = defStyle;
		mContext = context;
		init();
		setViews();
	}
	
	public void setDawinServerType(int type) {
		if(type != DawinConfig.DAWIN_SERVER_REAL && type != DawinConfig.DAWIN_SERVER_TEST) return;
		mDawinServerType = type;
	}
	
	private void init() {
		mIsTstoreInstalled = CommonUtils.isPackageInstalled(mContext, "com.skt.skaf.A000Z00040");
		mIsKakaoTalkInstalled = CommonUtils.isPackageInstalled(mContext, "com.kakao.talk");
		mIsKakaoStoryInstalled = CommonUtils.isPackageInstalled(mContext, "com.kakao.story");
		
		registPhoneStateListener();
		
		mConnectionManager = new BKConnectionManager(mContext);
		mImageDownloader = new BKImageDownloader(mContext);
		mConnectionManager.setOnConnectionStateListener(this);
		CommonUtils.getDeviceType(mContext);
		mErrorHandler = new BKErrorHandler(mContext);
		
		mDeviceDensity = CommonUtils.getDensity(mContext);
		
		if(mDeviceDensity == CommonUtils.DENSITY_LDPI) { // ldpi
			BKLog.i("-- LDPI");
			// 20141007 mdpi 기준 85% 
			mButtonSize = 40;
			mSkipButtonWidth = 55;
			mSkipButtonHeight = 51;
			mSkipDescWidth = 155;
			// 20141007 mdpi 기준  사이즈의 85%.
			mActionButtonWidth = 60;
			mActionButtonHeight = 60;
		} else if(mDeviceDensity == CommonUtils.DENSITY_MDPI) { // mdpi
			BKLog.i("-- MDPI");
			// 20141007 hdpi 기준 85% 
			mButtonSize = 47;
			mSkipButtonWidth = 65;
			mSkipButtonHeight = 60;
			mSkipDescWidth = 182;
			// 20141007 hdpi 기준 사이즈의 85%.
			mActionButtonWidth = 71;
			mActionButtonHeight = 71;
		} else if(mDeviceDensity == CommonUtils.DENSITY_HDPI) { // hdpi
			BKLog.i("-- HDPI");
			// 20141007 xhdpi 기준 70% 
			mButtonSize = 55;
			mSkipButtonWidth = 76;
			mSkipButtonHeight = 71;
			mSkipDescWidth = 214;
			// 20141007 xhdpi 기준 사이즈의 70%.
			mActionButtonWidth = 83;
			mActionButtonHeight = 83;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XHDPI) { // xhdpi ##################### 기준 사이즈 #######################
			BKLog.i("-- XHDPI");
			// 20141007 xhdpi를 기준으로 함.
			mButtonSize = 79;
			mSkipButtonWidth = 108;
			mSkipButtonHeight = 102;
			mSkipDescWidth = 305;
			// 20141007 xhdpi 기준이고 실제 버튼 사이즈로 설정함.
			mActionButtonWidth = 119;
			mActionButtonHeight = 119;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XXHDPI) { // xxdpi
			// 25% higher than xhdpi
			mButtonSize = 99;
			mSkipButtonWidth = 135;
			mSkipButtonHeight = 128;
			mSkipDescWidth = 381;
			// 20141007 xhdpi 기준 125%
			mActionButtonWidth = 149;
			mActionButtonHeight = 149;
		} else if(mDeviceDensity == CommonUtils.DENSITY_SXHDPI) { // sxhdpi
			// 20% higher than xxhdpi
			mButtonSize = 119;
			mSkipButtonWidth = 162;
			mSkipButtonHeight = 154;
			mSkipDescWidth = 457;
			// 20141007 xxhdpi 기준 120%
			mActionButtonWidth = 179;
			mActionButtonHeight = 179;
		}
		
		if(mTimeListener == null) {
			mTimeListener = new OnTimeListener() {
				@Override
				public void OnTime(int currMsec) {
					
					// 티커관련 처리.. 
					if(mTicker != null && mAdInfos != null) {
						int duration = Integer.parseInt(mAdInfos.getAdDuration());
						if(currMsec > 0 && currMsec <= duration) {
							BKLog.e("--------------------- onTime(" + currMsec + ")");
							int maxCount = mTicker.getTickerList().size();
							if(mCurrentTickerNum < maxCount) {
								TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
								
								if(mIsTickerShowing) {
									// 티커가 보여지는 상태에서 이곳에 들어오는 경우는 종료시간 체크하는 것으로 간주함.
									if(currMsec >= info.getEndViewTime()) {
										mHandler.sendEmptyMessage(MESSAGE_REMOVE_TICKER);
									}
								} else {
									// 현재 해당된 티커가 나와야 되는 시간이 맞는 경우, 티커를 보여주도록 한다.
									if(currMsec >= info.getStartViewTime() && currMsec <= info.getEndViewTime()) {
										mHandler.sendEmptyMessage(MESSAGE_HANDLE_TICKER);
									}
								}
							}
						}
					}
				}
			};
		}
	}
	
	public RelativeLayout.LayoutParams changePositionByNumber(RelativeLayout.LayoutParams param, int position) {
		RelativeLayout.LayoutParams result = new RelativeLayout.LayoutParams(param.width, param.height);
		if(position > 0 && position < 8) {
			switch(position) {
				case 1: // left top
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 2: // left center
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.CENTER_VERTICAL);
					break;
					
				case 3: // left bottom
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
					break;
					
				case 4: // center top
					result.addRule(RelativeLayout.CENTER_HORIZONTAL);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 5: // center bottom
					result.addRule(RelativeLayout.CENTER_HORIZONTAL);
					result.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
					break;
					
				case 6: // right top
					result.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 7: // right center
					result.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
					result.addRule(RelativeLayout.CENTER_VERTICAL);
					break;
			}
		} else return param;
		
		
		return result;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	
	@Override
	protected void onSizeChanged (int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		BKLog.d("====================on size changed=============================");
		BKLog.d("w : " + w + ", h : " + h + ", oldw : " + oldw + ", oldh : " + oldh);
		
		if(mVideoPlayer != null && oldw != w) {
			if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
				mCurrentOrientation = Configuration.ORIENTATION_PORTRAIT;
				mVideoPlayer.setCurrentOrientation(mCurrentOrientation);
				if(mPortParentWidth == -1 && mPortParentHeight == -1) {
					mPortParentWidth = w;
					mPortParentHeight = h;
				}
			} else {
				mCurrentOrientation = Configuration.ORIENTATION_LANDSCAPE;
				mVideoPlayer.setCurrentOrientation(mCurrentOrientation);
				if(mLandParentWidth == -1 && mLandParentHeight == -1) {
					mLandParentWidth = w;
					mLandParentHeight = h;
				}
			}
			mVideoPlayer.setParentViewSize(mCurrentOrientation, w, h);
			setVideoLayoutParam();
			
			// 20141128 기존에 다윈이 play중이 아니면 사이즈 셋팅이 안되도록 설정이 되어 다윈 영상 재생직전에 화면을 돌린경우 가로 사이즈 측정이 안되는 문제점이 있었다. 다윈 플레이 여부가 아닌, 티커가 있을때 설정하는 것으로 변경적용.
			if(mTicker != null && mAdInfos.isTickerAvailable()) {
				boolean isReady = mTicker.isReady(mCurrentOrientation);
				mTicker.setScreenSize(mCurrentOrientation, new ScreenSize(w, h));
				if(mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
					if(!isReady) {
						BKLog.e("land not ready!! " );
						setTickerSize();
					}
				} else {
					if(!isReady) {
						BKLog.e("port not ready!! " );
						setTickerSize();
					}
				}
			}
			
			if(mIsTickerShowing) {
				Message msg = new Message();
				msg.what = MESSAGE_HANDLE_TICKER;
				mHandler.sendMessageDelayed(msg, 100);
			}
		} else {
			BKLog.e("Wrong case!!! old width can not same as current width.");
		}
	}
	
	private void setVideoLayoutParam() {
		// TODO : 이전 소스 아랫부분에 주석처리했음. 비디오 픽스된 사이즈를 가지고 올 수 있는 경우 셋팅하는 것으로 설정하시오.
		BKLog.e("setVideoLayoutParam()");
		if(mVideoPlayer != null && mVideoLayout != null) {
			ScreenSize size = mVideoPlayer.getVideoSize();
			if(size.getWidth() > 0 && size.getHeight() > 0) {
				int parentWidth = -1, parentHeight = -1, topMargin = -1, bottomMargin = -1, leftMargin = -1, rightMargin = -1;
				if(mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
					parentWidth = mLandParentWidth;
					parentHeight = mLandParentHeight;
				} else {
					parentWidth = mPortParentWidth;
					parentHeight = mPortParentHeight;
				}
				
				// 가로
				if(parentWidth == size.getWidth()) {
					mLeftLayout.setVisibility(View.GONE);
					mRightLayout.setVisibility(View.GONE);
					BKLog.e("parent width same as video width. hide left, right view.");
				} else {
					int margin = parentWidth - size.getWidth();
					leftMargin = margin / 2;
					rightMargin = margin - leftMargin;
					
					LinearLayout.LayoutParams leftLayoutParam = (LinearLayout.LayoutParams) mLeftLayout.getLayoutParams();
					LinearLayout.LayoutParams rightLayoutParam = (LinearLayout.LayoutParams) mRightLayout.getLayoutParams();
					
					leftLayoutParam.width = leftMargin;
					rightLayoutParam.width = rightMargin;
					
					mLeftLayout.setLayoutParams(leftLayoutParam);
					mRightLayout.setLayoutParams(rightLayoutParam);
					
					mLeftLayout.setVisibility(View.VISIBLE);
					mRightLayout.setVisibility(View.VISIBLE);
					BKLog.e("parent width : " + parentWidth + ", video width : " + size.getWidth() + ", left margin : " + leftMargin + ", right margin : " + rightMargin);
				}
				
				// 세로
				if(parentHeight == size.getHeight()) {
					mTopLayout.setVisibility(View.GONE);
					mBottomLayout.setVisibility(View.GONE);
					BKLog.e("parent height same as video height. hide top, bottom view.");
				} else {
					int margin = parentHeight - size.getHeight();
					topMargin = margin / 2;
					bottomMargin = margin - topMargin;
					
					LinearLayout.LayoutParams topLayoutParam = (LinearLayout.LayoutParams) mTopLayout.getLayoutParams();
					LinearLayout.LayoutParams bottomLayoutParam = (LinearLayout.LayoutParams) mBottomLayout.getLayoutParams();
					
					topLayoutParam.height = topMargin;
					bottomLayoutParam.height = bottomMargin;
					
					mTopLayout.setLayoutParams(topLayoutParam);
					mBottomLayout.setLayoutParams(bottomLayoutParam);
					
					mTopLayout.setVisibility(View.VISIBLE);
					mBottomLayout.setVisibility(View.VISIBLE);
					BKLog.e("parent height : " + parentHeight + ", video Height : " + size.getHeight() + ", top margin : " + topMargin + ", bottom margin : " + bottomMargin);
				}
				
				LinearLayout.LayoutParams videoBottomParam = (LinearLayout.LayoutParams) mVideoBottomLayout.getLayoutParams();
				BKLog.e("####################################################################################");
				BKLog.e("BEFORE  Bottom layout width : " + videoBottomParam.width + ", height : " + videoBottomParam.height);
				BKLog.e("SET Bottom layout width : " + LinearLayout.LayoutParams.MATCH_PARENT + ", height : " + size.getHeight());
				BKLog.e("####################################################################################");
				
				LinearLayout.LayoutParams newVideoBottomParam = 
						new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, size.getHeight());
				newVideoBottomParam.weight = 0;
				newVideoBottomParam.gravity = Gravity.CENTER;
				
				mVideoBottomLayout.setLayoutParams(newVideoBottomParam);
				
				LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) mVideoLayout.getLayoutParams();
				BKLog.e("BEFORE video layout width : " + param.width + ", height : " + param.height);
				BKLog.e("AFTER  video layout width : " + size.getWidth() + ", height : " + size.getHeight());
				BKLog.e("####################################################################################");
				
				LinearLayout.LayoutParams videoLayoutParam = new LinearLayout.LayoutParams(size.getWidth(), size.getHeight());
				mVideoLayout.setLayoutParams(videoLayoutParam);
				
			}
		}
	}
	
	private void setTickerSize() {
		if(mTicker != null && mTicker.getTickerList() != null && mTicker.getTickerList().size() > 0) { // 20141121 비정상인경우 걸러내는 것으로함.
			RelativeLayout.LayoutParams param = 
				new RelativeLayout.LayoutParams(mTicker.getTickerList().get(mCurrentTickerNum).getWidth(mCurrentOrientation), 
					mTicker.getTickerList().get(mCurrentTickerNum).getHeight(mCurrentOrientation));
			param = changePositionByNumber(param, mTicker.getTickerList().get(mCurrentTickerNum).getPosition());
			if(mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
				mLandTickerButton.setLayoutParams(param);
			} else {
				mPortTickerButton.setLayoutParams(param);
			}
		}
	}
	
	@Override
	protected void onDraw (Canvas canvas) {
		super.onDraw(canvas);
	}

	@SuppressLint ("DrawAllocation")
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
	    int width = displayMetrics.widthPixels;
    	int height = displayMetrics.heightPixels;
    	
    	int rightMargin = width - r;
    	int topMargin = t;
    	int bottomMargin = height - b;
    	int leftMargin = l;
    	
		/*BKLog.d("Parent width : " + mParentWidth + "px, parent height : " + mParentHeight + "px");
		BKLog.d("display width : " + width + ", display height : " + height);
		mVideoPlayer.changeDimension();*/
	}
	
	/*public void changeLayoutMode(int mode) {
		mVideoPlayer.changeVideoMode(mode);
	}*/
	
	
	/**
	 * must call onResume at activity's onResume();
	 */
	public void onResume() {
		// finish Activity when call event
		BKLog.e("onResume dawinadplayer");
		/*if(mCurrentCallState == CALL_STATE_INCOMING || mCurrentCallState == CALL_STATE_OUTGOING) {
			BKLog.w("Call finish");
			initializeVideoView();
			if(mPlayFinishListener != null) {
				 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
			}
		} else */
		if(mIsSnsShareClicked){
			reset();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_SNS_SHARE);
			}
		} else if(mIsTickerClicked) {
			reset();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
			}
		} else if(mIsClickviewerShown) {
			reset();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
			}
		} else if(mIsOnPauseCalled) {
			BKLog.e("isPauseCalled!!");
			reset();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		}
	}
	
	private void setViews() {
		LinearLayout mainLayout = new LinearLayout(mContext);
		mainLayout.setOrientation(LinearLayout.VERTICAL);
		mainLayout.setGravity(Gravity.CENTER);
		mainLayout.setBackgroundColor(Color.parseColor("#000000"));
		
		LinearLayout.LayoutParams mainParam = 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
		
		mainParam.setMargins(0, 0, 0, 0);
		
		mVideoLayout = new RelativeLayout(mContext);
		
		LinearLayout.LayoutParams videoLayoutParam = 
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		videoLayoutParam.weight = 0;
		videoLayoutParam.gravity = Gravity.CENTER;
		
		// 20150107
		// 다윈에 Full screen 영역을 제공하는 매체의 경우 세로모드에서 영상 상하단 빈 공간에(검은영역) 버튼이 들어가는 것이 보기 싫다는 요청이 들어와 상 하단 빈공간을 채울 layout 추가하는 형식 적용함.
		// Top과 bottom에 빈 layout을 추가하여 영상 사이즈 판별 후 세로값이 fix됐을때 VideoLayout의 height값을 fix하고 상하 빈 공간에 들어가는 Layout의 높이를 weight 1로 채워버림.
		mTopLayout = new RelativeLayout(mContext);
//		mTopLayout.setBackgroundColor(Color.parseColor("#ff0000"));
		mBottomLayout = new RelativeLayout(mContext);
//		mBottomLayout.setBackgroundColor(Color.parseColor("#ffff00"));
		
		// 20150113
		// 모든 경우(가로/세로 구분없이)에 버튼은 영상 영역 내부로 와야된다고 시나리오 변경함. 주석일자 당시 메일 검색.
		mLeftLayout = new RelativeLayout(mContext);
//		mLeftLayout.setBackgroundColor(Color.parseColor("#00ff00"));
		mRightLayout = new RelativeLayout(mContext);
//		mRightLayout.setBackgroundColor(Color.parseColor("#0000ff"));
		
		LinearLayout.LayoutParams emptyAreaParamTB = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
		emptyAreaParamTB.weight = 1;
		
		LinearLayout.LayoutParams emptyAreaParamLR = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
		emptyAreaParamLR.weight = 1;
		
		RelativeLayout.LayoutParams buttonLayoutParam = 
				new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		
		mVideoPlayer = new BKVideoPlayer(mContext);
		
		RelativeLayout.LayoutParams videoParam = 
				new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		videoParam.setMargins(0, 0, 0, 0);
		videoParam.addRule(RelativeLayout.CENTER_IN_PARENT);
		
		
		mVideoLayout.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null && !mIsVideoClickProcessing) {
					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("") && mVideoPlayer != null) {
						mIsVideoClickProcessing = true;
						lockClickEvents(false);
						cancelAllTimer();
						if(mVideoPlayer.canPause()) {
							mVideoPlayer.pause();
						}
						showProgress();
						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
					}
				}
			}
		});
		
//		mVideoLayout.setOnTouchListener(new OnTouchListener() {
//			
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				if(mAdInfos != null && !mIsVideoClickProcessing) {
//					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("")) {
////						BKLog.e("ontouch");
//						mIsVideoClickProcessing = true;
//						lockClickEvents(false);
//						cancelAllTimer();
//						if(mVideoPlayer.canPause()) {
//							mVideoPlayer.pause();
//						}
//						showProgress();
//						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
//					}
//				}
//				
//				return false;
//			}
//		});
		
		mVideoPlayer.setOnVideoErrorListener(new OnVideoErrorListener() {
			
			@Override
			public void onVideoError(MediaPlayer mp, int errorCode) {
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=9");
				}
				reset();
				Log.e(getClass().getName(), "DawinAdPlayer video player error.. finish dawin ad player");
				
			}
		});
		
		mVideoPlayer.setOnSizeAdjustListener(new OnSizeAdjustListener() {
			
			@Override
			public void onSizeAdjusted(int which) {
				switch(which) {
					case BKVideoPlayer.ADJUSTED_VIDEO_SIZE:
						BKLog.e("OnSizeAdjustListener - onSizeAdjusted -- ADJUST_VIDEO_SIZE");
						setVideoLayoutParam();
						break;
				}
			}
		});
		
		mSnsLayout = new LinearLayout(mContext);
		mSnsLayout.setOrientation(LinearLayout.HORIZONTAL);
		mSnsLayout.setVisibility(View.GONE);
		
		mEventLayout = new LinearLayout(mContext);
		mEventLayout.setVisibility(View.GONE);
		
		mCallLayout = new LinearLayout(mContext);
		mCallLayout.setVisibility(View.GONE);
		
		mDownloadLayout = new LinearLayout(mContext);
		mDownloadLayout.setVisibility(View.GONE);
		
		mMapLayout = new LinearLayout(mContext);
		mMapLayout.setVisibility(View.GONE);
		
		mSkipLayout = new LinearLayout(mContext);
		mSkipLayout.setVisibility(View.GONE);
		
		RelativeLayout.LayoutParams buttonParams = 
				new RelativeLayout.LayoutParams(mActionButtonWidth, mActionButtonHeight);
		buttonParams.setMargins(6, 0, 0, 0);
		
		RelativeLayout.LayoutParams skipLayoutParam = 
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		
		mVideoLayout.addView(mVideoPlayer, videoParam);
		mVideoLayout.addView(mSnsLayout, buttonLayoutParam);
		mVideoLayout.addView(mEventLayout, buttonLayoutParam);
		mVideoLayout.addView(mCallLayout, buttonLayoutParam);
		mVideoLayout.addView(mDownloadLayout, buttonLayoutParam);
		mVideoLayout.addView(mMapLayout, buttonLayoutParam);
		mVideoLayout.addView(mSkipLayout, skipLayoutParam);
		
		
		
		// 20140919 me2day 서비스 종료로 인해 Me2day관련 삭제함
		mFacebookButton = new ImageButton(mContext);
		mFacebookButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.FACEBOOK, mAdInfos.getTrackingUrl(AdInfos.FACEBOOK) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.FACEBOOK));
				}
			}
		});
		
		mTwitterButton = new ImageButton(mContext);
		mTwitterButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.TWITTER, mAdInfos.getTrackingUrl(AdInfos.TWITTER) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.TWITTER));
				}
			}
		});
		
		// init other buttons
		mCallButton = new ImageButton(mContext);
		mCallButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.CALL, mAdInfos.getClickThrough(AdInfos.CALL), null);
				}
				
			}
		});
		
		mMapButton = new ImageButton(mContext);
		mMapButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.MAP, mAdInfos.getTrackingUrl(AdInfos.MAP) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.MAP));
				}
				
			}
		});
		
		mEventButton = new ImageButton(mContext);
		mEventButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.EVENT, mAdInfos.getTrackingUrl(AdInfos.EVENT) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.EVENT));
				}
				
			}
		});
		
		mDownloadButton = new ImageButton(mContext);
		mDownloadButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
						mIsDawinPlaying = false;
						mIsClickviewerShown = true;
					}
					showProgress();
					/* 20130806 예외적으로 Download Action 클릭에서만 리다이렉트 시키지 않는 것으로 서버팀과 협의함
					  기획팀의 만행으로(만들어준 테스트 앱 확인 안해봄) 기존에는 클릭뷰어에서 처리하던 것을 클릭뷰어를 
					  띄우지 않고 처리하는 것으로 변경함 */
					// 태그 전송용 url
					String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
					mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
					
					// 스토어 연결에 사용할 url
					// 2013.09.30 화면클릭시에도 다운로드가 가능하도록 하기위해서 코드 중복배제를 위해 메소드로 분리
					downloadApp(mAdInfos.getClickThrough(AdInfos.DOWNLOAD).trim());
					
//					기존 클릭뷰어로 보내던 동작 주석처리
//					handleActionClick(AdInfos.DOWNLOAD, mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.DOWNLOAD));
				}
			}
		});
		
		
		// Add sns buttons to sns layout.
		mSnsLayout.addView(mFacebookButton, buttonParams);
		mSnsLayout.addView(mTwitterButton, buttonParams);
		
		// Add call button to call layout
		mCallLayout.addView(mCallButton, buttonParams);
		
		// Add download button to download layout
		mDownloadLayout.addView(mDownloadButton, buttonParams);
		
		// Add map button to map layout
		mMapLayout.addView(mMapButton, buttonParams);
		
		// Add event button to event layout
		mEventLayout.addView(mEventButton, buttonParams);
		
		mSkipButton = new ImageButton(mContext);
		mSkipButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					showProgress();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					cancelAllTimer();
					
					mConnectionManager.sendRequest(REQUEST_SKIP, mAdInfos.getSkipTag(), null);
				}
			}
		});
		
		mSkipDescriptionButton = new ImageButton(mContext);
		
		mFacebookButton.setVisibility(View.GONE);
		mTwitterButton.setVisibility(View.GONE);
		mSkipButton.setVisibility(View.GONE);
		mSkipDescriptionButton.setVisibility(View.GONE);
		mDownloadButton.setVisibility(View.GONE);
		mMapButton.setVisibility(View.GONE);
		mCallButton.setVisibility(View.GONE);
		mEventButton.setVisibility(View.GONE);
		
		
		
		LinearLayout.LayoutParams skipButtonParam = 
				new LinearLayout.LayoutParams(mSkipButtonWidth, mSkipButtonHeight);
		
		LinearLayout.LayoutParams skipDescriptionButtonParam = 
			new LinearLayout.LayoutParams(mSkipDescWidth, mSkipButtonHeight);
		
		
		mSkipLayout.addView(mSkipButton, skipButtonParam);
		mSkipLayout.addView(mSkipDescriptionButton, skipDescriptionButtonParam);
		
		// Progress bar
		mProgress = new ProgressBar(mContext, null, android.R.attr.progressBarStyle);
		mProgress.setVisibility(View.GONE);
		RelativeLayout.LayoutParams progressParam = 
				new RelativeLayout.LayoutParams(mButtonSize, mButtonSize);
		progressParam.addRule(RelativeLayout.CENTER_IN_PARENT);
		mVideoLayout.addView(mProgress, progressParam);
		
		
		
		mVideoPlayer.setOnVideoErrorListener(new BKVideoPlayer.OnVideoErrorListener() {
			
			@Override
			public void onVideoError(MediaPlayer mp, int errorCode) {
				
				
				if(mVideoPlayer != null) {
					mVideoPlayer.pause();
					reset();
				}
				
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
				}
				
				if(mErrorListener != null) {
					mErrorListener.onError(mp, errorCode, 0);
				}
				
			}
		});
				
		
		mVideoPlayer.setOnVideoStartListener(new BKVideoPlayer.OnVideoStartListener() {
			
			@Override
			public void onVideoStarted() {
				// Handler에서 보내는 메세지.. 
				BKLog.i("onVideoStarted =============>");
				mIsDawinPlaying = true;
				try {
					if(mAdInfos != null) {
						if(!mIsStartTagSended) {
							mIsStartTagSended = true;
							mConnectionManager.sendRequest(REQUEST_START, mAdInfos.getStartTag(), null);
						}
						hideProgress();
						if(!mIsChargeTagSendSucceed) {
							if(!mIsQuarterMinAd) {
								BKLog.e("ChargeTime : " + mChargeTime);
								int chargeTimeDelay = (int) (mChargeTime * 0.8);
								startTimer(CHARGE_TIMER, chargeTimeDelay, mTimerPeriod);
							}
							
						}
						startTimer(SKIP_TIMER, mTimerDelay, mTimerPeriod);
						startTimer(QUARTER_CHECK_TIMER, mTimerDelay, mTimerPeriod);
						if(mAdInfos.isTickerAvailable()) {
							startTimer(COMBINED_TIMER, mTimerDelay, 500);
						}
						
						showActionLayout();
						
						if(mAdInfos.isTickerAvailable()) {
							startTimer(COMBINED_TIMER, mTimerPeriod, 500);
						}
						
						if(mAdInfos.isSnsShareAvailable()) {
							addSnsShareView(mAdInfos.getSnsShareList());
						}
						
						if(mAdInfos.isAvailable(AdInfos.SKIP) || mAdInfos.isAvailable(AdInfos.SKIP_DESCRIPTION)) {
							mSkipLayout.setVisibility(View.VISIBLE);
						} else {
							mSkipLayout.setVisibility(View.GONE);
						}
					}
					
				} catch(Exception e) {
					// 잘못된 상황임.
					
				}
				
				
			}
		});
		
		
		mVideoPlayer.setOnPlayFinishListener(new BKVideoPlayer.OnPlayFinishListener() {
			@Override
			public void onPlayFinished(MediaPlayer mp) {
				if(mVideoPlayer != null && mVideoPlayer.getCurrentState() == BKVideoPlayer.STATE_PLAYING) { // 20141216
					try {
						mVideoPlayer.pause();
						mVideoPlayer.stop();
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
				mIsDawinPlaying = false;
				showProgress();
				// 과금테그 전송여부 확인
				if(mIsChargeTagSendSucceed) {
					if(mAdInfos != null) {
						mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
					} else {
						hideProgress();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
						}
					}
				} else {
					if(mIsQuarterMinAd) {
						if(mAdInfos != null) {
							mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
						} else {
							hideProgress();
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
							}
						}
					} else {
						if(mAdInfos != null) {
							mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
						} else {
							hideProgress();
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
							}
						}
					}
				}
			}
		});
		
		// 20150113 영상 내부에 모든 버튼을 위치시키는 것으로 정책 변경하여 좌, 우 빈공간에 쓸 에이아웃 추가.
		mVideoBottomLayout = new LinearLayout(mContext);
		mVideoBottomLayout.setOrientation(LinearLayout.HORIZONTAL);
		mVideoBottomLayout.setGravity(Gravity.CENTER);
//		LinearLayout.LayoutParams videoLayoutBottomParam = 
//				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		
		// 1. 상단 여백용 레이아웃 추가
		mainLayout.addView(mTopLayout, emptyAreaParamTB);
		
		// 2. 중간 비디오 영역 바닥 레이아웃 셋팅
		// 2-1. 비디오레이아웃 바닥 좌측 여백 레이아웃 추가
		mVideoBottomLayout.addView(mLeftLayout, emptyAreaParamLR);
		// 2-2. 콘텐츠가 표시될 레이아웃 추가
		mVideoBottomLayout.addView(mVideoLayout, videoLayoutParam);
		// 2-3. 비디오레이아웃 바닥 우측 여백 레이아웃 추가
		mVideoBottomLayout.addView(mRightLayout, emptyAreaParamLR);
		
		// 3. 중간 비디오 영역 바닥 레이아웃 추가
		mainLayout.addView(mVideoBottomLayout, videoLayoutParam);
		
		// 4. 바닥 여백용 레이아웃 추가
		mainLayout.addView(mBottomLayout, emptyAreaParamTB);
		
		// 5. 최종 메인레이아웃을 현재 View에 추가
		DawinAdPlayer.this.addView(mainLayout, mainParam);
	}
	
	/**
	 * 2013.09.30 화면클릭으로 다운로드가 가능하도록 하기위해 변경함.
	 * 광고에서 지정한 앱 다운로드시에 사용함.
	 * @param downloadUrl : T-store 또는 Android 지원하는 형식의 주소 사용.
	 * @return
	 */
	public boolean downloadApp(String downloadUrl) {
		if(downloadUrl == null || downloadUrl.equals("")) return false;
		// 20131001 어쨋던 외부로 나간 후 종료하는 것이므로, 이 경우 클릭뷰어 종료로 처리함.(기존 다운로드가 그렇게 처리중이었음)
		mIsClickviewerShown = true;
		if(downloadUrl.contains("tstore://")) {
			BKLog.e("T store app!! : " + downloadUrl);
			String key = downloadUrl.substring(9);
			if(mIsTstoreInstalled) {
				Intent intent = new Intent();
				intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
				intent.setClassName("com.skt.skaf.A000Z00040", "com.skt.skaf.A000Z00040.A000Z00040");
				intent.setAction("COLLAB_ACTION");
				intent.putExtra("com.skt.skaf.COL.URI", key.getBytes());
				intent.putExtra("com.skt.skaf.COL.REQUESTER", "A000Z00040");
				mContext.startActivity(intent);
			} else {
				/* 20130809 기획팀은 앱 설치가 되지 않은 경우 설치 안내페이지로 연결해달라는 말에 동의를 했으나 자세한 설명을 해주지 않았음에도 불구하고 이렇게 되는 것이 아니라며 또다시 내용을 수정함
				 * 현재 설치 안내페이지에서 http://tsto.re/앱정보 형식으로 외부 브라우저로 연결하도록 변경함.*/
				BKLog.e("tstore not installed. go to install guide page.");
				String[] splitString = downloadUrl.split("PRODUCT_VIEW/");
				String downloadInfo = (splitString[1].split("/"))[0];
				BKLog.e("download info : " + downloadInfo);
				
				Intent i = new Intent(Intent.ACTION_VIEW);
				Uri u = Uri.parse("http://tsto.re/" + downloadInfo);
				i.setData(u); 
				mContext.startActivity(i);
			}   
			BKLog.e(key);
			
			
		} else if(downloadUrl.contains("market://")) {
			BKLog.e("google market app!!" + downloadUrl);
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.addCategory(Intent.CATEGORY_DEFAULT);
			intent.setData(Uri.parse(downloadUrl));
			mContext.startActivity(intent);
		} else {
			// 예외상황이라서 기타 오류로 종료 처리.
			mIsClickviewerShown = false;
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			}
			return false;
		}
		return true;
	}
	
	
	
	public void initTimers() {
		// skip timer initialize
		if(mSkipTimer == null) {
			mSkipTimer = new Timer();
		} else {
			mSkipTimer.cancel();
			mSkipTimer.purge();
			if(mSkipTimerTask != null) {
				mSkipTimerTask.cancel();
			}
		}
		
		if(mSkipTimerTask == null) {
			mSkipTimerTask = new TimerTask() {
				@Override
				public void run() {
					try {
						
						if(mVideoPlayer != null && mVideoPlayer.isPlaying() && mVideoPlayer.getCurrentPosition() > (mAdInfos != null?mAdInfos.getIconShowTime(AdInfos.SKIP) : 5000)) {
							mHandler.sendEmptyMessage(MESSAGE_SHOW_SKIP);
							cancelTimer(SKIP_TIMER);
						}
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
			};
		}
		
		// charge timer initialize
		if(mChargeTimer == null) {
			mChargeTimer = new Timer();
		} else {
			mChargeTimer.cancel();
			mChargeTimer.purge();
			if(mChargeTimerTask != null) {
				mChargeTimer.cancel();
			}
		}
		
		if(mChargeTimerTask == null) {
			mChargeTimerTask = new TimerTask() {
				@Override
				public void run() {
					BKLog.d("Charge Timer ----");
					try {
						if(mVideoPlayer != null && mVideoPlayer.getCurrentPosition() > mChargeTime && mVideoPlayer.isPlaying()) {
							if(mAdInfos != null) {
								mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
							}
							cancelTimer(CHARGE_TIMER);
						}
					} catch(Exception e) {
						e.printStackTrace();
						cancelAllTimer();
					}
				}
			};
		}
		
		// quarter timer initialize
		if(mQuarterTimer == null) {
			mQuarterTimer = new Timer();
		} else {
			mQuarterTimer.cancel();
			mQuarterTimer.purge();
			if(mQuarterTimerTask != null) {
				mQuarterTimerTask.cancel();
			}
		}
		
		if(mQuarterTimerTask == null) {
			mQuarterTimerTask = new TimerTask() {
				@Override
				public void run() {
					try {
						if(mVideoPlayer != null && mVideoPlayer.isPlaying()) {
							if(mVideoPlayer.getCurrentPosition() > mQuarter && mVideoPlayer.getCurrentPosition() < mQuarter2) {
								if(mCurrentQuarter != 2) {
									mCurrentQuarter = 2;
									BKLog.d("Quarter2!");
									
									if(mAdInfos != null) {
										mConnectionManager.sendRequest(REQUEST_QUARTER, mAdInfos.getQuarterTag(1), null);
									}
									mLastSendedTag = 1;
								}
							} else if(mVideoPlayer.getCurrentPosition() > mQuarter2 && mVideoPlayer.getCurrentPosition() < mQuarter3) {
								if(mCurrentQuarter != 3) {
									mCurrentQuarter = 3;
									BKLog.d("Quarter3!");
									if(mAdInfos != null) {
										mConnectionManager.sendRequest(REQUEST_QUEARTER2, mAdInfos.getQuarterTag(2), null);
									}
									
									mLastSendedTag = 2;
								}
							} else if(mVideoPlayer.getCurrentPosition() > mQuarter3) {
								mCurrentQuarter = 4;
								BKLog.d("Quarter4!");
								if(mAdInfos != null) {
									mConnectionManager.sendRequest(REQUEST_QUEARTER3, mAdInfos.getQuarterTag(3), null);
								}
								mLastSendedTag = 3;
								cancelTimer(QUARTER_CHECK_TIMER);
							}
						}
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
			};
		}
		
		// timer for ticker
		if(mTimer == null) {
			mTimer = new Timer();
		} else { 
			mTimer.cancel();
			mTimer.purge();
			if(mTimerTask != null) {
				mTimerTask.cancel();
			}
		}
		
		if(mTimerTask == null) {
			mTimerTask = new TimerTask() {
				@Override
				public void run() {
					if(mVideoPlayer != null && mTimeListener != null) {
						try {
							mTimeListener.OnTime(mVideoPlayer.getCurrentPosition());
						} catch(Exception e) {
							mTimeListener.OnTime(-1);
							cancelTimer(COMBINED_TIMER);
						}
						
					}
					
				}
			};
		}
	}
	
	private void cancelAllTimer() {
		cancelTimer(CHARGE_TIMER);
		cancelTimer(SKIP_TIMER);
		cancelTimer(QUARTER_CHECK_TIMER);
		cancelTimer(COMBINED_TIMER);
	}
	
	private void cancelTimer(int which) {
		switch(which) {
			case CHARGE_TIMER:
				if(mIsChargeTimerRunning) {
					mIsChargeTimerRunning = false;
					if(mChargeTimer != null) {
						mChargeTimer.cancel();
						mChargeTimer.purge();
						mChargeTimer = null;
					}
					
					if(mChargeTimerTask != null) {
						mChargeTimerTask.cancel();
						mChargeTimerTask = null;
					}
				}
				
				break;
				
			case SKIP_TIMER:
				if(mIsSkipTimerRunning) {
					mIsSkipTimerRunning = false;
					if(mSkipTimer != null) {
						mSkipTimer.cancel();
						mSkipTimer.purge();
						mSkipTimer = null;
					}
					
					if(mSkipTimerTask != null) {
						mSkipTimerTask.cancel();
						mSkipTimerTask = null;
					}
				}
				
				break;
				
			case QUARTER_CHECK_TIMER:
				if(mIsQuarterTimerRunning) {
					mIsQuarterTimerRunning = false;
					if(mQuarterTimer != null) {
						mQuarterTimer.cancel();
						mQuarterTimer.purge();
						mQuarterTimer = null;
					}
					
					if(mQuarterTimerTask != null) {
						mQuarterTimerTask.cancel();
						mQuarterTimerTask = null;
					}
				}
				
				break;
				
			case COMBINED_TIMER:
				BKLog.e("finish combined timer");
				if(mIsTimerRunning) {
					mIsTimerRunning = false;
					if(mTimer != null) {
						mTimer.cancel();
						mTimer.purge();
						mTimer = null;
					}
					
					if(mTimerTask != null) {
						mTimerTask.cancel();
						mTimerTask = null;
					}
				}
				break;
				
		}
	}
	
	private void startTimer(int which, int delay, int period) {
		switch(which) {
			case QUARTER_CHECK_TIMER:
				if(mQuarterTimer != null && mQuarterTimerTask != null && !mIsQuarterTimerRunning) {
					mIsQuarterTimerRunning = true;
					mQuarterTimer.schedule(mQuarterTimerTask, delay, period);
				}
				break;
				
			case SKIP_TIMER:
				if(mSkipTimer != null && mSkipTimerTask != null && !mIsSkipTimerRunning) {
					mIsSkipTimerRunning = true;
					mSkipTimer.schedule(mSkipTimerTask, delay, period);
				}
				break;
				
			case CHARGE_TIMER:
				if(mChargeTimer != null && mChargeTimerTask != null && !mIsChargeTimerRunning) {
					mIsChargeTimerRunning = true;
					mChargeTimer.schedule(mChargeTimerTask, delay, period);
				}
				break;
				
			case COMBINED_TIMER:
				if(mTimer != null && mTimerTask != null && !mIsTimerRunning) {
					mIsTimerRunning = true;
					mTimer.schedule(mTimerTask, delay, period);
				}
				break;
		}
	}
	
	
	private void handleActionClick(int which, String handleInfo, String pageUrl) {
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_BUTTON_CLICK);
		}
		if(mVideoPlayer != null && mVideoPlayer.canPause()) {
			mVideoPlayer.pause();
		}
		BKLog.e("actionClick!!! : " + handleInfo);
		mIsDawinPlaying = false;
		if(which == AdInfos.CALL) {
			showCallDialog(handleInfo);
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle():""), pageUrl);
		}
	}
	
	private void handleScreenClick(String handleInfo, String pageUrl) {
		if(mAdInfos == null) return;
		
		// 20131001 화면 클릭의 경우 클릭뷰어가 뜨던 외부 브라우저로 가던 다른 액션이 일어나므로 중복되는 코드이기 때문에 주석처리함.
//		if(mPlayFinishListener != null) {
//			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SCREEN_CLICK);
//		}
		cancelAllTimer();
		mIsDawinPlaying = false;
		if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_CALL) {
			showProgress();
			handleActionClick(AdInfos.CALL, mAdInfos.getVideoclickThrough(), null);
		} else if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_DOWNLOAD) {
			if(mAdInfos != null) {
				lockClickEvents(false);
				showProgress();
				// 20131001 다운로드, 전화에 한해서 클릭태그 전송시 각각의 액션에 대한 Tracking tag를 전송한다.(화면클릭태그는 실제주소를 전송해서 오류발생함)
				// 2013년 9월 30일 오후 6:33 메일 확인
				String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
				mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
				downloadApp(mAdInfos.getVideoclickThrough());
			} else {
				
			}
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle() : ""), pageUrl);
		}
	}
	
	
	private String getActionButtonParameter() {
		String result = "";
		
		result = "&lq=" + String.valueOf(mLastSendedTag) + "&pay=" + (mIsChargeTagSendSucceed? "1": "0");
		
		return result;
	}
	
	
	private void showBrowserDialog(String path, String title, String pageUrl) {
		mIsClickviewerShown = true;
		if(mAdInfos.getBrowserMode().equals(AdInfos.BROWSER_MODE_DEFAULT_BROWSER)) {
			// 실제 브라우저로 넘기는 부분
			Intent i = new Intent(Intent.ACTION_VIEW); 
			Uri u = Uri.parse(path); 
			i.setData(u); 
			mContext.startActivity(i);
		} else {
			BKDialog dialog = new BKDialog();
			dialog.setOnDialogStateListener(new OnDialogStateListener() {
				
				@Override
				public void onDialogShown() {
					BKLog.w("------- Dialog show");
				}
				
				@Override
				public void onDialogDismissed() {
					BKLog.w("------- Dialog dismissed");
				}
			});
			
//			dialog.setMargin(mDialogMarginRate);
			Intent intent = new Intent(mContext, dialog.getClass());
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_URL, path);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_REAL_URL, pageUrl);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_TITLE, title);
			
			((Activity) mContext).startActivityForResult(intent, BKDialog.ACTION_CLICKVIEWER);
		}
	}
	
	private void addSnsShareView(ArrayList<SnsShare> list) {
		mSnsBottomLayout = new RelativeLayout(mContext); //  SNS Sahre 기능을 사용하는경우 이 layout을 보여줌
		
		RelativeLayout.LayoutParams snsBottomLayoutParam = 
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		snsBottomLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		snsBottomLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		snsBottomLayoutParam.setMargins(0, 5, 5, 0);
		
		
		mSnsShareButton = new ImageButton(mContext);
		mSnsShareButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mIsButtonClickable) {
					mSnsShareButton.setVisibility(View.GONE);
					mSnsShareContentLayout.setVisibility(View.VISIBLE);
				}
			}
		});
		
		mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SNS_SHARE), mSnsShareButton, mAdInfos.isIconShowDirectly(AdInfos.SNS_SHARE));
		
		LinearLayout.LayoutParams snsShareButtonParam = 
			new LinearLayout.LayoutParams(mButtonSize, mButtonSize);
		snsShareButtonParam.setMargins(0, 5, 5, 0);
		
		mSnsBottomLayout.addView(mSnsShareButton, snsShareButtonParam);
		
		mSnsShareContentLayout = new LinearLayout(mContext); // SNS Share 버튼 클릭시 나오는 Layout.
		mSnsShareContentLayout.setOrientation(LinearLayout.VERTICAL); 
		mSnsShareContentLayout.setBackgroundColor(Color.parseColor("#E6171717"));
		
		LinearLayout.LayoutParams snsShareContentLayoutParam = 
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		int padding = (int) Math.round(mButtonSize / 7);
		mSnsShareContentLayout.setPadding(padding, padding, padding, padding);
		
		LinearLayout snsShareContentMainLayout = new LinearLayout(mContext); // SNS Share시 나오는 Layout의 내용을 담을 Layout
		snsShareContentMainLayout.setOrientation(LinearLayout.VERTICAL); 
		snsShareContentMainLayout.setGravity(Gravity.CENTER);
		
		LinearLayout.LayoutParams snsShareContentMainLayoutParam = 
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		
		// SNS Buttons put into SNS button container.
		LinearLayout snsButtonContainer = new LinearLayout(mContext);
		snsButtonContainer.setOrientation(LinearLayout.HORIZONTAL);
		snsButtonContainer.setGravity(Gravity.CENTER);
		
		LinearLayout.LayoutParams snsButtonContainerParam =
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		snsButtonContainerParam.setMargins(0, (int) Math.round(mButtonSize / 6), 0, (int) Math.round(mButtonSize / 6));
		
		for(int i = 0; i < list.size(); i++) {
			ImageButton snsBtn = new ImageButton(mContext);
			mImageDownloader.download(list.get(i).getIconUrl(), snsBtn, true);
			final SnsShare snsInfo = list.get(i);
			snsBtn.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					if(mAdInfos != null && mIsButtonClickable) {
						handleSnsClick(snsInfo);
					}
					
				}
			});
			
			
			LinearLayout.LayoutParams snsBtnParam = new LinearLayout.LayoutParams(mButtonSize, mButtonSize);
			if(i == 0) {
				snsBtnParam.setMargins((int) Math.round(mButtonSize / 5), 0, (int) Math.round(mButtonSize / 5), 0);
			} else {
				snsBtnParam.setMargins(0, 0, (int) Math.round(mButtonSize / 5), 0);
			}
			
			snsButtonContainer.addView(snsBtn, snsBtnParam);
		}
		
		ImageButton cancelButton = new ImageButton(mContext);
		mImageDownloader.download(mAdInfos.getIconUrl(IconInfoParser.ICON_SNS_CANCEL), cancelButton, true);
		
		cancelButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mIsButtonClickable) {
					mSnsShareContentLayout.setVisibility(View.GONE);
					mSnsShareButton.setVisibility(View.VISIBLE);
				}
			}
		});
		
		
		LinearLayout.LayoutParams cancelButtonParam =
			new LinearLayout.LayoutParams((int) Math.round((mButtonSize * 0.8)), (int) Math.round((mButtonSize * 0.8)));
		cancelButtonParam.setMargins((int) Math.round((mButtonSize / 5) * 1.5), 0, 0, 0);
		
		snsButtonContainer.addView(cancelButton, cancelButtonParam);
		
		snsShareContentMainLayout.addView(snsButtonContainer, snsButtonContainerParam);
		
		
		mSnsShareContentLayout.setVisibility(View.GONE);
		mSnsShareContentLayout.addView(snsShareContentMainLayout, snsShareContentMainLayoutParam);
		mSnsBottomLayout.addView(mSnsShareContentLayout, snsShareContentLayoutParam);
		mVideoLayout.addView(mSnsBottomLayout, snsBottomLayoutParam);
	}
	
	private void handleSnsClick(SnsShare snsInfo) {
		String snsName = snsInfo.getSnsName();
		if(!snsName.equals("etc")) {
			mIsSnsShareClicked = true;
			lockClickEvents(false);
			cancelAllTimer();
			if(mVideoPlayer.canPause()) {
				mVideoPlayer.pause();
			}
			mIsDawinPlaying = false;
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BY_SNS_SHARE);
			}
			
			mConnectionManager.sendRequest(REQUEST_SEND_TAG, snsInfo.getClickTracking() + getActionButtonParameter(), null);
		}
		
		if(snsName.equals("kakaoTalk")) {
			if(mIsKakaoTalkInstalled) {
				try {
					CommonUtils.shareKakao(mContext, CommonUtils.KAKAO_TALK, null, snsInfo.getMessage(), snsInfo.getClickThrough());
					
				} catch(UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			} else {
				downloadApp("market://details?id=com.kakao.talk");
			}
		} else if(snsName.equals("kakaoStory")) {
			if(mIsKakaoStoryInstalled) {
				try {
					CommonUtils.shareKakao(mContext, CommonUtils.KAKAO_STORY, null, snsInfo.getMessage(), snsInfo.getClickThrough());
				} catch(UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			} else {
				downloadApp("market://details?id=com.kakao.story");
			}
		} else if(snsName.equals("etc")) {
			BKLog.i("etc button clicked~~~~~~");
			if(!mIsSnsEtcButtonClicked) {
				mConnectionManager.sendRequest(REQUEST_SEND_TAG, snsInfo.getClickTracking() + getActionButtonParameter(), null);
				mIsSnsEtcButtonClicked = true;
			} else {
				BKLog.w("Etc already clicked!!");
			}
			
			CommonUtils.setTextToPrimaryClipboard(mContext, snsInfo.getClickThrough(), "복사됐습니다.");
			mSnsShareContentLayout.setVisibility(View.GONE);
			mSnsShareButton.setVisibility(View.VISIBLE);
		} else {
			boolean flag = false;
			StringBuilder sb = new StringBuilder();
			if(snsName.equals("facebook")) {
				sb.append("http://www.facebook.com/sharer/sharer.php?").append("&u=").append(snsInfo.getClickThrough());
				flag = true;
			} else if(snsName.equals("twitter")) {
				sb.append("https://twitter.com/intent/tweet?text=").append(snsInfo.getMessage());
				sb.append("&url=").append(snsInfo.getClickThrough());
				flag = true;
			}
			
			Intent i = new Intent(Intent.ACTION_VIEW); 
			Uri u = Uri.parse(flag ? sb.toString() : snsInfo.getClickThrough()); 
			i.setData(u); 
			mContext.startActivity(i);
		}
	}
	
	
	/**
	 * Dawin 개편
	 * Ticker 추가기능 관련 메소드
	 */
	private void addTickerView(ArrayList<TickerAd> list) {
		mPortTickerButton = new ImageButton(mContext);
		mLandTickerButton = new ImageButton(mContext);
		mPortTickerButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					showProgress();
					handleTickerClick();
				}
				
			}
		});
		mLandTickerButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					showProgress();
					handleTickerClick();
				}
				
			}
		});
		
		mPortTickerButton.setVisibility(View.GONE);
		mLandTickerButton.setVisibility(View.GONE);
		RelativeLayout.LayoutParams tickerButtonParam =
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		mVideoLayout.addView(mPortTickerButton, tickerButtonParam);
		mVideoLayout.addView(mLandTickerButton, tickerButtonParam);
	}
	
	private void showTicker() {
		if(!mIsTickerShowing) {
			// 현재 보이지 않는 상태이므로 티커관련 변수 초기화 후 보여줌.
			if(mTicker != null) {
				startTimer(COMBINED_TIMER, mTimerPeriod, 300);
			}
		}
	}
	
	private void handleTickerView() {
		if(mTicker != null) {
			TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
			BKLog.e("handleTickerView");
			if(mIsTickerShowing) {
				/*BKLog.e("Current orientation : " + (CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE? "landscape" : "portrait"));
				BKLog.e("Size change!!! w : " + info.getWidth(CommonUtils.getOrientation(mContext)) + ", h : " + info.getHeight(CommonUtils.getOrientation(mContext)));
				mTickerButton.getLayoutParams().width = info.getWidth(mCurrentOrientation);
				mTickerButton.getLayoutParams().height = info.getHeight(mCurrentOrientation);
				BKLog.e("tickerbutton. w : " + mTickerButton.getLayoutParams().width + ", h : " + mTickerButton.getLayoutParams().height);*/
				changeTickerByOrientation();
			} else {
				// ticker를 보여줘야하는 시점!!
				mPortTickerButton.setBackgroundDrawable(new BitmapDrawable(info.getBitmap()));
				mLandTickerButton.setBackgroundDrawable(new BitmapDrawable(info.getBitmap()));
				
				// 20141128 기존 아래의 Orientation에 따라 위치 및 크기값을 넣어줬는데, 시작 당시(영상 준비중 progress circle이 도는 시점)에 전환을 하면 한쪽 orientation에 대한 티커 버튼에 위치값이 제대로 들어가지 않는 문제점이 발생하여 값을 받은 시점에 모두 계산을 해서 넣는 것으로 수정함.
				RelativeLayout.LayoutParams portParam = new RelativeLayout.LayoutParams(info.getWidth(Configuration.ORIENTATION_PORTRAIT), info.getHeight(Configuration.ORIENTATION_PORTRAIT));
				portParam = changePositionByNumber(portParam, info.getPosition());
				mPortTickerButton.setLayoutParams(portParam);
				
				RelativeLayout.LayoutParams landParam = new RelativeLayout.LayoutParams(info.getWidth(Configuration.ORIENTATION_LANDSCAPE), info.getHeight(Configuration.ORIENTATION_LANDSCAPE));
				landParam = changePositionByNumber(landParam, info.getPosition());
				mLandTickerButton.setLayoutParams(landParam);
				
				BKLog.e("############################################################################################################################################");
				BKLog.e("mLandTickerButton");
				BKLog.e("############################################################################################################################################");
				
				if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
					mPortTickerButton.setVisibility(View.VISIBLE);
					mPortTickerButton.refreshDrawableState();
				} else {
					mLandTickerButton.setVisibility(View.VISIBLE);
					mLandTickerButton.refreshDrawableState();
				}
				
				mIsTickerShowing = true;
				BKLog.e("ShowTicker!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! in HandleTickerView");
			}
		}
	}
	
	private void changeTickerByOrientation() {
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE) {
			mPortTickerButton.setVisibility(View.GONE);
			mLandTickerButton.setVisibility(View.VISIBLE);
		} else {
			mPortTickerButton.setVisibility(View.VISIBLE);
			mLandTickerButton.setVisibility(View.GONE);
		}
	}
	
	public void removeTickerView() {
		mPortTickerButton.setVisibility(View.GONE);
		mLandTickerButton.setVisibility(View.GONE);
		mIsTickerShowing = false;
		mCurrentTickerNum++;
		BKLog.e("currentTickernumber : " + mCurrentTickerNum + ", ticker size : " + mTicker.getTickerList().size());
		if(mCurrentTickerNum >= mTicker.getTickerList().size()) {
			cancelTimer(COMBINED_TIMER);
			initializeTicker();
		}
	}
	
	private void handleTickerClick() {
		BKLog.e("handle Ticker click!!");
		if(mVideoPlayer != null) {
			if(mVideoPlayer.getCurrentState() == BKVideoPlayer.STATE_PLAYING) {
				mVideoPlayer.pause();
			}
		}
		
		lockClickEvents(false);
		cancelAllTimer();
		
		if(mIsTickerShowing && mTicker != null) {
			final TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
			if(info != null) {
				String program = info.getProgram();
				
				if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BY_TICKER);
				mIsTickerClicked = true;
				
				if(program.equals("download")) {
					// 스토어 연결에 사용할 url
					// 2013.09.30 화면클릭시에도 다운로드가 가능하도록 하기위해서 코드 중복배제를 위해 메소드로 분리
					mConnectionManager.sendRequest(REQUEST_SEND_TAG, info.getClickTracking() + getActionButtonParameter(), null);
					downloadApp(info.getClickThrough().trim());
				} else if(program.equals("call")) {
					final String phoneNumber = info.getClickThrough();
					if(mCurrentPhoneState == ServiceState.STATE_IN_SERVICE) {
						AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, phoneNumber, "취소", "통화", new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								if(mPlayFinishListener != null) {
									mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
								}
							}
						} , new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								mCurrentCallState = CALL_STATE_OUTGOING;
								mConnectionManager.sendRequest(REQUEST_SEND_TAG, info.getClickTracking() + getActionButtonParameter(), null);
								CommonUtils.callTo(mContext, phoneNumber);
							}
						});
						dialog.setOnKeyListener(new Dialog.OnKeyListener() {

				            @Override
				            public boolean onKey(DialogInterface arg0, int keyCode,
				                    KeyEvent event) {
				                if (keyCode == KeyEvent.KEYCODE_BACK) {
				                    arg0.dismiss();
				                    if(mPlayFinishListener != null) {
				                    	BKLog.i("Back Key pressed in call dialog-can make call case");
										mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
									}
				                }
				                return true;
				            }
				        });
						dialog.show();
						TextView msg = (TextView) dialog.findViewById(android.R.id.message);
						msg.setGravity(Gravity.CENTER);
						
					} else {
						AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, "전화 기능을 이용할 수 없는 상태입니다.", "확인", null, new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								if(mPlayFinishListener != null) {
									mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
								}
							}
						}, null);
						dialog.show();
						TextView msg = (TextView) dialog.findViewById(android.R.id.message);
						msg.setGravity(Gravity.CENTER);
					}
					
				} else {
					String tickerBtnUrl = info.getClickTracking() + getActionButtonParameter();
					Intent i = new Intent(Intent.ACTION_VIEW); 
					Uri u = Uri.parse(tickerBtnUrl);
					i.setData(u); 
					mContext.startActivity(i);
				}
			} else {
				if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		} else {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
		}
	}
	
	private void downloadTickerImage(ArrayList<TickerAd> list) {
		ArrayList<String> tickerUrl = new ArrayList<String>();
		
		for(int i = 0; i < list.size(); i++) {
			tickerUrl.add(list.get(i).getImageUrl());
		}
		
		if(tickerUrl.size() > 0) {
			BKImageDownloader downloader = new BKImageDownloader(mContext);
			downloader.setOnBitmapDownloadFinishListener(new OnBitmapDownloadFinishListener() {
				
				@Override
				public void onBitmapDownloadFinished(ArrayList<Bitmap> bitmaps) {
					try {
						BKLog.e("onBitmapDownloadFinished---- bitmap count : " + bitmaps.size());
						if(bitmaps != null && bitmaps.size() > 0) {
							mTicker = new TickerAdBuilder(mAdInfos.getTickerList(), bitmaps).build(mCurrentOrientation, 
								new ScreenSize((mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortParentWidth : mLandParentWidth), 
									(mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortParentHeight : mLandParentHeight)));
							
							if(!mIsTickerShowing && isDawinAdPlaying()) {
								showTicker();
							}
						}
					} catch(Exception e) {
						e.printStackTrace();
						mHandler.sendEmptyMessage(MESSAGE_REMOVE_TICKER);
					}
				}
			});
			downloader.downloadBitmaps(tickerUrl);
		} else {
			return;
		}
	}
	
	public boolean isDawinAdPlaying() {
		return mIsDawinPlaying;
	}
	
	/*private void showBrowser(String path) {
		hideProgress();
		initializeVideoView();
		
		if(path == null) return;
		Intent i = new Intent(Intent.ACTION_VIEW); 
		Uri u = Uri.parse(path);
		i.setData(u);
		mContext.startActivity(i);
	}*/
	
	/**
	 * @deprecated
	 * this method deprecated.
	 * @param orientation : orientation to set mode
	 * @param mode : video display mode
	 * @see BKVideoView, Configuration
	 */
	public void setVideoMode(int orientation, int mode) {
		switch(orientation) {
			case Configuration.ORIENTATION_LANDSCAPE:
//				mLandscapeVideoMode = mode;
				break;
				
			case Configuration.ORIENTATION_PORTRAIT:
//				mPortraitVideoMode = mode;
				break;
		}
//		mVideoView.setVideoMode(orientation, mode);
	}
	
	
	/**
	 * show ad with given parameters.
	 * @param gcd : goods code
	 * @param mcd : media code
	 * @param pcd : page code
	 * @param scd : screen code
	 * @param ccd : category code
	 * @return : -1 returns when any parameter is null or 0 length. otherwise returns 0.
	 */
	
	public int showAd(String gcd, String mcd, String pcd, String scd, String ccd) {
		if(gcd == null || gcd.equals("") || mcd == null || mcd.equals("") || pcd == null || pcd.equals("") || scd == null || scd.equals("") || ccd == null || ccd.equals("")) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			reset();
			return -1;
		}
		
		mAdInfoParameter = getAdInfoParameter(gcd, mcd, pcd, scd, ccd);
		if(mAdInfoParameter == null) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			reset();
			return -1;
		}
		
		// remove ad informations
		mAdInfos = null;
		
		// 20141202 하단 VideoPlayer 보여주는 부분은 혹시 videoPlayer가 Visible상태가 아닌경우에 surface가 destroy상황일 것이므로 미리 추가해줌.
		BKLog.e("prepare surface");
		DawinAdPlayer.this.setVisibility(View.VISIBLE);
		if(mVideoPlayer != null) {
			mVideoPlayer.setVisibility(View.VISIBLE);
			showProgress();
		}
		
		try {
			Thread.sleep(300);
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		
		mAdinfoRequestUrl = (mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL);
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, mAdinfoRequestUrl, mAdInfoParameter);
		
		
		if(mErrorHandler.isFailedWorkAvailable()) {
			new Handler().postDelayed(new Runnable() {

				@Override
				public void run() {
					mErrorHandler.sendFailedRequest();
				}
				
			}, 1000);
			
		}
		return 0;
	}
	
	public void setDialogMarginRate(int marginRate) {
		mDialogMarginRate = marginRate;
	}
	
	public void showTestAd(String url) {
		showProgress();
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, url, null);
	}
	
	private JSONObject getAdInfoParameter(String gcd, String mcd, String pcd, String scd, String ccd) {
		String uid = CommonUtils.getStringPreference(mContext, DawinConfig.KEY_UID);
		
		JSONObject result = new JSONObject();
		try {
			result.put("gcd", gcd);
			result.put("mcd", mcd);
			result.put("pcd", pcd);
			result.put("scd", scd);
			result.put("ccd", ccd);
			// 20130731 버전코드 추가함.
			result.put("ver", "2.0");
			// 20131125 queryString 뒤에 UID를 붙여서 요청보내는 작업 추가함(preferences에 저장된 UID 이용)
			if(uid != null && !uid.equals("")) {
				result.put("uid", uid);
			}
			
		} catch(JSONException e) {
			result = null;
		}
		
		return result;
	}
	
	public int getCurrentState() {
		return (mVideoPlayer != null? mVideoPlayer.getCurrentState(): -1);
	}
	
	
	private void prepareVideo() {
		if(mAdInfos == null || mVideoPlayer == null) {
			if(mPlayFinishListener != null) { // 20150107 호핀 크래쉬 리포트로 널 포인터 날 가능성 있는 부분을 확인하여 널체크구문 추가함.
				mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			}
			return;
		}
		try {
			this.setVisibility(View.VISIBLE);
			mMediaController = new MediaController(mContext);
			mMediaController.setAnchorView(mVideoPlayer);
//			mVideoView.setMediaController(mMediaController);
			
			if(mVideoPlayer != null) {
				mVideoPlayer.setVisibility(View.VISIBLE);
				if(mAdInfos.getMediaFileUrl() == null) {
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
					}
					return;
				}
				
				mVideoPlayer.setVideoURI(mAdInfos.getMediaFileUrl());
				mVideoPlayer.requestFocus();
				mVideoPlayer.setOnPreparedListener(new BKVideoPlayer.OnPreparedListener() {
					
					@Override
					public void onPrepared(MediaPlayer mp) {
						if(mAdInfos == null) {
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
							}
							return;
						}
						showProgress();
						initTimers();
						if(mp != null) { // 20141216 몽키 테스트에서 해당 부분 null pointer exception 떨어져서 처리구문 추가함.
							BKLog.d("media width : " + mp.getVideoWidth() + ", media height : " + mp.getVideoHeight());
							BKLog.d("greatest common measure : " + CommonUtils.getGreatestCommonMeasure(mp.getVideoWidth(), mp.getVideoHeight()));
							
							setVideoLayoutParam();
							
							int duration = mp.getDuration();
							
							if(duration < 16000) {
								// smaller than 16000 -> it's 15sec ad
								BKLog.e("============================== 15sec ad ================================");
								mIsQuarterMinAd = true;
							} else {
								BKLog.e("============================== other sec ad ================================");
								mIsQuarterMinAd = false;
							}
							
							try {
								if(mAdInfos.getChargeTime() > duration) {
									mChargeTime = duration - 500;
								} else {
									mChargeTime = mAdInfos.getChargeTime();
								}
								
								BKLog.e("Duration : " + duration + ", chargetime : " + mChargeTime + "real chargetime : " + mAdInfos.getChargeTime());
							} catch(NumberFormatException e) {
								mChargeTime = mAdInfos.getChargeTime() - 1000;
							}
							
							
							if(mAdInfos != null) {
								BKLog.i("------------- Start new video");
								mLastSendedTag = 0;
								mAdDuration = mp.getDuration();
								mQuarter = mAdInfos.getQuarterTime(1);
								mQuarter2 = mAdInfos.getQuarterTime(2);
								mQuarter3 = mAdInfos.getQuarterTime(3);
//								setVideoPlayerSize();
								mVideoPlayer.start();
								BKLog.e("Duration : " + mp.getDuration());
								if(!mSkipButton.isShown()) {
									BKLog.i("::> BKSkipTimer start");
									int skipTimerDelay = (int) (mAdInfos.getIconShowTime(AdInfos.SKIP) * 0.8);
									startTimer(SKIP_TIMER, skipTimerDelay, mTimerPeriod);
								}
							}
							
							if(mPreparedListener != null) {
								mPreparedListener.onPrepared();
							}
						} else {
							reset();
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
							}
						}
						
					}
				});
			}
			
		} catch(Exception e) {
			e.printStackTrace();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
			reset();
		}
		
	}
	
	public void onConfigurationChanged() {
		int orientation;
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			orientation = Configuration.ORIENTATION_PORTRAIT;
		} else {
			orientation = Configuration.ORIENTATION_LANDSCAPE;
		}
		if(mVideoPlayer != null) {
			mVideoPlayer.refreshDrawableState();
		}
	}
	
	
	private void showProgress() {
		lockClickEvents(false);
		mProgress.setVisibility(View.VISIBLE);
	}
	
	private void hideProgress() {
		lockClickEvents(true);
		mProgress.setVisibility(View.GONE);
	}
	
	
	/**
	 * lock clickable views
	 * @param isClickable : false to lock buttons
	 */
	private void lockClickEvents(boolean isClickable) {
		mVideoLayout.setClickable(isClickable);
		mFacebookButton.setClickable(isClickable);
		mTwitterButton.setClickable(isClickable);
		mSkipButton.setClickable(isClickable);
		mEventButton.setClickable(isClickable);
		mCallButton.setClickable(isClickable);
		mMapButton.setClickable(isClickable);
		mDownloadButton.setClickable(isClickable);
		// 20141216 클릭이벤트 락걸때 추가된 티커와 sns 함께 적용함.
		if(mPortTickerButton != null) mPortTickerButton.setClickable(isClickable);
		if(mLandTickerButton != null) mLandTickerButton.setClickable(isClickable);
		if(mSnsShareButton != null) mSnsShareButton.setClickable(isClickable);
		mIsButtonClickable = isClickable;
	}
	
	
	
	private void reset() {
		BKLog.e("InitializeVideoView!!!!!!!!!!!!!!!!!!!!!!!");
		// remove or stop schedulers
		cancelAllTimer();
		mCurrentCallState = CALL_STATE_IDLE;
		mIsClickviewerShown = false;
		mIsOnPauseCalled = false;
		mIsSnsShareClicked = false;
		mIsSnsEtcButtonClicked = false;
		
		// initialize videoview click
		mIsVideoClickProcessing = false;
		if(mVideoPlayer != null) {
			mVideoPlayer.reset();
		}
		mHandler.sendEmptyMessage(MESSAGE_RESET_VIEW);
		lockClickEvents(false);
		
		// init ticker variables
		mIsDawinPlaying = false;
		mIsTickerShowing = false;
		
		// initialize tag
		mIsStartTagSended = false;
		// initialize videoview click
		mIsVideoClickProcessing = false;
		
		DawinAdPlayer.this.removeAllViews();
		initAdditionalView();
		setViews();
		initializeTicker();
	}
	
	private void initializeTicker() {
		BKLog.e("initializeTicker()");
		if(mTicker != null && mTicker.getTickerList() != null) {
			for(int i = 0; i < mTicker.getTickerList().size(); i++) {
				TickerInfo info = mTicker.getTickerList().get(i);
				Bitmap bitmap = info.getBitmap();
				if(bitmap != null) {
					bitmap.recycle();
					BKLog.i(i + " bitmap recycled.");
				}
			}
			mTicker = null;
		}
		
		
		
		mIsTickerShowing = false;
		mCurrentTickerNum = 0;
		if(mPortTickerButton != null) {
			mPortTickerButton.setVisibility(View.GONE);
		}
		
		if(mLandTickerButton != null) {
			mLandTickerButton.setVisibility(View.GONE);
		}
	}
	
	private void checkIconImage(int actionMode) {
		if(mAdInfos == null) {
			return;
		}
		switch(actionMode) {
			case AdInfos.ACTION_MODE_SNS:
				if(mAdInfos.getIconUrl(AdInfos.FACEBOOK) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.FACEBOOK), mFacebookButton, mAdInfos.isIconShowDirectly(AdInfos.FACEBOOK));
				}
				
				if(mAdInfos.getIconUrl(AdInfos.TWITTER) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.TWITTER), mTwitterButton, mAdInfos.isIconShowDirectly(AdInfos.TWITTER));
				}
				break;
				
			case AdInfos.ACTION_MODE_CALL:
				if(mAdInfos.getIconUrl(AdInfos.CALL) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.CALL), mCallButton, mAdInfos.isIconShowDirectly(AdInfos.CALL));
				}
				break;
				
			case AdInfos.ACTION_MODE_DOWNLOAD:
				if(mAdInfos.getIconUrl(AdInfos.DOWNLOAD) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.DOWNLOAD), mDownloadButton, mAdInfos.isIconShowDirectly(AdInfos.DOWNLOAD));
				}
				break;
				
			case AdInfos.ACTION_MODE_EVENT:
				if(mAdInfos.getIconUrl(AdInfos.EVENT) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.EVENT), mEventButton, mAdInfos.isIconShowDirectly(AdInfos.EVENT));
				}
				break;
				
			case AdInfos.ACTION_MODE_MAP:
				if(mAdInfos.getIconUrl(AdInfos.MAP) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.MAP), mMapButton, mAdInfos.isIconShowDirectly(AdInfos.MAP));
				}
				break;
				
		}
		
//		if(mAdInfos.getIconUrl(AdInfos.SKIP) != null) {
//			mImageDownloader.download(DawinConfig.IMG_SKIP_URL, mSkipButton, false);
//		}
		// 20140919 아이콘 이미지 하드코딩 제거함. 이미지 체크 필요!!
		if(mAdInfos.isAvailable(AdInfos.SKIP)) {
			if(mAdInfos.getIconUrl(AdInfos.SKIP) != null) {
				mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SKIP), mSkipButton, false);
			}
		}
		
		if(mAdInfos.isAvailable(AdInfos.SKIP_DESCRIPTION)) {
			if(mAdInfos.getIconUrl(AdInfos.SKIP_DESCRIPTION) != null) {
				mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SKIP_DESCRIPTION), mSkipDescriptionButton, true);
			}
		}
	}
	
	private void showActionLayout() {
		if(mAdInfos != null) {
			switch(mAdInfos.getActionMode()) {
				case AdInfos.ACTION_MODE_SNS:
					mSnsLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_CALL:
					mCallLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_DOWNLOAD:
					mDownloadLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_EVENT:
					mEventLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_MAP:
					mMapLayout.setVisibility(View.VISIBLE);
					break;
			}
		}
	}
	
	
	public int destroy() {
		cancelAllTimer();
		if(mVideoPlayer != null) {
			mVideoPlayer.release();
		}
		mIsDawinPlaying = false;
		mVideoPlayer = null;
		this.removeAllViews();
		System.gc();
		return 0;
	}
	
	private void initAdditionalView() {
		if(mSnsBottomLayout != null) {
			mSnsBottomLayout.removeAllViews();
			mSnsBottomLayout = null;
		}
		mIsDawinPlaying = false;
	}
	
	private void resetViewStates() {
		BKLog.i("-------- Reset views state");
		// 이미 초기화 된 적이 있는 뷰의 경우에 호출.
		mSnsLayout.setVisibility(View.GONE);
		mEventLayout.setVisibility(View.GONE);
		mCallLayout.setVisibility(View.GONE);
		mDownloadLayout.setVisibility(View.GONE);
		mMapLayout.setVisibility(View.GONE);
		mSkipLayout.setVisibility(View.GONE);
		mFacebookButton.setVisibility(View.GONE);
		mTwitterButton.setVisibility(View.GONE);
		mSkipButton.setVisibility(View.GONE);
		mSkipDescriptionButton.setVisibility(View.VISIBLE);
		mDownloadButton.setVisibility(View.GONE);
		mMapButton.setVisibility(View.GONE);
		mCallButton.setVisibility(View.GONE);
		mEventButton.setVisibility(View.GONE);
		mProgress.setVisibility(View.GONE);
		// 20141202 아래 코드를 활성화 시켜버리면 재요청시 surface가 이미 release 됐다는 오류를 뱉아내고 종료함. 따라서 주석처리.
//		if(mVideoPlayer != null) mVideoPlayer.setVisibility(View.GONE);
	}
	
	private void showCallDialog(String phoneNumber) {
		if(mAdInfos == null) {
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			}
			return;
		}
		
		// 20130624 추가. 전화 버튼을 눌렀을 때 요청 보내는 걸로 수정
		final String callTracking = mAdInfos.getTrackingUrl(IconInfoParser.ICON_CALL) + getActionButtonParameter();
		hideProgress();
		reset();
		final String num = phoneNumber;
		if(mCurrentPhoneState == ServiceState.STATE_IN_SERVICE) {
			AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, phoneNumber, "취소", "통화", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
					}
				}
			} , new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					mCurrentCallState = CALL_STATE_OUTGOING;
					mIsClickviewerShown = true;
					mConnectionManager.sendRequest(REQUEST_PHONE_CLICK, callTracking, null);
					CommonUtils.callTo(mContext, num);
				}
			});
			dialog.setOnKeyListener(new Dialog.OnKeyListener() {

	            @Override
	            public boolean onKey(DialogInterface arg0, int keyCode,
	                    KeyEvent event) {
	                if (keyCode == KeyEvent.KEYCODE_BACK) {
	                    arg0.dismiss();
	                    if(mPlayFinishListener != null) {
	                    	BKLog.i("Back Key pressed in call dialog-can make call case");
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
						}
	                }
	                return true;
	            }
	        });
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
			
		} else {
			AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, "전화 기능을 이용할 수 없는 상태입니다.", "확인", null, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
					}
				}
			}, null);
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
		}
	}
	
	
	/**
	 * 화면 클릭 이벤트 등 뷰에 관련된 이벤트 발생이 필요한 경우 반환함.
	 * @return View : VideoView를 담고있는 컨테이너.
	 */
	public View getScreenContainerView() {
		return mVideoLayout;
	}
	
	
	public void setOnPlayFinishListener(OnPlayFinishListener listener) {
		mPlayFinishListener = listener;
	}
	
	public void setOnErrorListener(OnErrorListener listener) {
		mErrorListener = listener;
	}
	
	public void setOnPreparedListener(OnPreparedListener listener) {
		mPreparedListener = listener;
	}
	
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	public String getXmlString() {
		return xmlString;
	}
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	
	@Override
	public void onRequestFinished(int whichRequest, HttpResponse result, String extractString) {
		BKLog.i("Request success!!!!!!!");
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				BKLog.i("Request ad info receive success!!");
				// 새로 정보를 받은 경우 과금테그 flag 초기화함.
				mIsChargeTagSendSucceed = false;
				xmlString = extractString;
				BKAdInfoParser parser = new BKAdInfoParser(extractString);
				mAdInfos = parser.parse();
				if(mAdInfos != null && !mAdInfos.isParsingProblemOccured()) { // 20141216 파싱문제여부 체크구문 추가. 문제가 있는경우 True 리턴되므로 false인 경우 진행함.
					mAdInfoRetryCount = 0; // 현재 분기문 조건에 만족하는 경우는 정상이라고 판단 하므로 기존에 변경됐을지도 모르는 재시도횟수 카운트용 변수 초기화
					if(mAdInfos != null) {
						String adId = mAdInfos.getAdId();
						
						if(adId != null && Integer.parseInt(adId) != DawinConfig.SERVER_MSG_NO_APPLICABLE_AD) {
							BKLog.e("Action mode : " + mAdInfos.getActionMode());
							if(mAdInfos.isTickerAvailable()) {
								downloadTickerImage(mAdInfos.getTickerList());
							}
							checkIconImage(mAdInfos.getActionMode());
							prepareVideo();
							
							try {
								if(mAdInfos.isTickerAvailable()) {
									addTickerView(mAdInfos.getTickerList());
								}
							} catch(Exception e) {
								e.printStackTrace();
							}
						} else {
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NO_APPLICABLE_AD);
							}
							hideProgress();
							DawinAdPlayer.this.setVisibility(View.GONE);
						}
					}
				} else {
					// 20141216 최홍석팀장님 --> 파싱 문제시 3회 재시도로 수정지시함. 여기서 3회 재시도 구문 추가.
					BKLog.w("Parsing problem occured!!!");
					if(mAdInfoRetryCount >= MAX_RETRY_COUNT) {
						// finish retry. 뷰 종료 또는 에러처리
						mAdInfoRetryCount = 0; // 맥시멈 시도횟수 초과로 시도횟수체크용 변수 초기화
						hideProgress();
//						Toast.makeText(mContext, "광고 정보 수신 실패", Toast.LENGTH_SHORT).show();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AD_INFO_RECEIVE_FAIL);
						}
						// 광고정보요청 실패 로그 서버전송.
						String errorUrl = (DawinConfig.isDebugMode?ADINFO_ERROR_LOG_DEV:ADINFO_ERROR_LOG_REL) + mAdinfoRequestUrl;
						mErrorHandler.sendErrorTag(errorUrl);
					} else {
						mAdInfoRetryCount++;
						mConnectionManager.sendRequest(REQUEST_AD_INFOS, mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL, mAdInfoParameter);
						BKLog.e("Parsing failed. retry..( " + mAdInfoRetryCount + ")");
					}
				}
				
				
				break;
				
			case REQUEST_START:
				BKLog.i("Start tag send success");
				break;
				
			case REQUEST_QUARTER:
				BKLog.i("Quarter tag send success");
				break;
				
			case REQUEST_QUEARTER2:
				BKLog.i("Quarter2 tag send success");
				break;
				
			case REQUEST_QUEARTER3:
				BKLog.i("Quarter3 tag send success");
				break;
				
			case REQUEST_FINISHED:
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				reset();
				BKLog.i("Finish tag send success");
				break;
				
			case REQUEST_SKIP:
				BKLog.i("Skip tag send success");
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				reset();
				break;
				
			case REQUEST_ERROR:
				BKLog.i("Error tag send success");
				break;
				
			case REQUEST_CHARGE:
				mIsChargeTagSendSucceed = true;
				if(mIsQuarterMinAd && mAdInfos != null) {
					mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
				} else {
					hideProgress();
					BKLog.e("====================================> Charge tag send success");
				}
				
				break;
				
			case REQUEST_PHONE_CLICK:
				BKLog.i("PhoneTag send success");
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send success");
				break;
			
		}
	}

	@Override
	public void onRequestError(int whichRequest, int errorCode, String message) {
		BKLog.e("Request error!!!!!!!");
		BKLog.e("Error code : " + errorCode + ", request : " + whichRequest);
		
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				if(errorCode == BKConnectionManager.NETWORK_DISCONNECTED) {
					mAdInfoRetryCount = 0; // 네트워크가 끊어진 경우 더이상 시도하지 않게 되므로 사용했을지도 모르는 시도횟수 체크용 변수 초기화
//					Toast.makeText(mContext, "네트워크가 끊어졌습니다. 상태 확인 후 다시 이용해 주세요", Toast.LENGTH_SHORT).show();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NETWORK_DISCONNECTED);
					}
					reset();
				} else {
					if(mAdInfoRetryCount >= MAX_RETRY_COUNT) {
						mAdInfoRetryCount = 0; // 맥시멈 시도횟수 초과로 시도횟수체크용 변수 초기화
						// finish retry. 뷰 종료 또는 에러처리
						hideProgress();
//						Toast.makeText(mContext, "광고 정보 수신 실패", Toast.LENGTH_SHORT).show();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AD_INFO_RECEIVE_FAIL);
						}
						// 광고정보요청 실패 로그 서버전송.
						String errorUrl = (DawinConfig.isDebugMode?ADINFO_ERROR_LOG_DEV:ADINFO_ERROR_LOG_REL) + mAdinfoRequestUrl;
						mErrorHandler.sendErrorTag(errorUrl);
					} else {
						mAdInfoRetryCount++;
						mConnectionManager.sendRequest(REQUEST_AD_INFOS, mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL, mAdInfoParameter);
						BKLog.e("Ad info receive failed. retry..( " + mAdInfoRetryCount + ")");
					}
				}
				break;
				
			case REQUEST_START:
				// do nothing
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=2");
				}
				
				break;
				
			case REQUEST_QUARTER:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=3");
				}
				break;
				
			case REQUEST_QUEARTER2:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=4");
				}
				break;
				
			case REQUEST_QUEARTER3:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=5");
				}
				break;
				
			case REQUEST_FINISHED:
				// 정상종료처럼 바로 진행
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=6");
				}
				reset();
				break;
				
			case REQUEST_SKIP:
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=7");
				}
				reset();
				break;
				
			case REQUEST_ERROR:
				// do nothing
				break;
				
			case REQUEST_CHARGE:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=8");
				}
				handleChargeRequestError(whichRequest);
				break;
				
			case REQUEST_PHONE_CLICK:
				BKLog.i("requestPhoneClickError");
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send error");
				break;
			
		}
		
	}
	
	private boolean handleChargeRequestError(int currRequest) {
		if(mChargeTagRetryCount >= MAX_RETRY_COUNT) {
			// finish retry. save failed list.
			if(mAdInfos != null) {
				mErrorHandler.saveFailedWork(mAdInfos.getChargeTag());
			}
			if(mIsQuarterMinAd && mAdInfos != null) {
				mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
			} else {
				hideProgress();
				reset();
			}
			
			return true;
		} else {
			mChargeTagRetryCount++;
			if(mAdInfos != null) {
				mConnectionManager.sendRequest(currRequest, mAdInfos.getEndTag(), null);
			}
			BKLog.e("Ad info receive failed. retry..( " + mChargeTagRetryCount + ")");
			return false;
		}
	}
	
	public void onPause() {
		// 20141127 개뜬금포 터지게 onPause가 들어온 상황이라면, 대부분 home key 또는 lock screen의 경우임. 이때 동영상을 종료함.
		mIsOnPauseCalled = true;
		lockClickEvents(false);
		cancelAllTimer();
		if(mVideoPlayer != null && mVideoPlayer.getCurrentState() == BKVideoPlayer.STATE_PLAYING) {
			mVideoPlayer.pause();
			BKLog.i("Stop videoPlayer when video is playing called after onPause().");
		}
	}
	
	public void onDestroy() {
		try { // 20141216 몽키 테스트에서 BKVideoPlayer의 start timer가 종료 후에도 계속해서 돌아가는 정확한 원인 발견 못하여 추가함.
			if(mVideoPlayer != null) {
				mVideoPlayer.release();
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
		cancelAllTimer();
		destroy();
	}
	
	public void onBackPressed() {
		cancelAllTimer();
		destroy();
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BACK_KEY_PRESSED);
		}
	}

	@Override
	public void onDialogShown() {
	}
	
	@Override
	public void onDialogDismissed() {
		hideProgress();
	}
	
}
